using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
using System.IO;

namespace SP
{
    class Testbed : MainForm
    {
        public Testbed()
        {
            this.Load += new EventHandler(_HandleLoad);
            this.generateNSaveButton.Click += new EventHandler(_HandleGenerateAndSave);
            this.generateButton.Click += new EventHandler(_HandleGenerateOnly);
            this.saveButton.Click += new EventHandler(_HandleSaveShader);
            this.loadButton.Click += new EventHandler(_HandleLoadShader);
            this.newButton.Click += new EventHandler(_HandleNewShader);

            mSaveResultDlg = new System.Windows.Forms.SaveFileDialog();
            mSaveResultDlg.DefaultExt = ".fx";
            mSaveResultDlg.Filter = "Fx Files (*.fx)|*.fx";

            mSaveShaderDlg = new System.Windows.Forms.SaveFileDialog();
            mSaveShaderDlg.DefaultExt = ".xml";
            mSaveShaderDlg.Filter = "Xml Shader Files (*.xml)|*.xml";

            mLoadShaderDlg = new System.Windows.Forms.OpenFileDialog();
            mLoadShaderDlg.DefaultExt = ".xml";
            mLoadShaderDlg.Filter = "Xml Shader Files (*.xml)|*.xml";
        }


        private void _HandleLoad(System.Object sender, System.EventArgs args)
        {
            // add reactor
            ReactorDB.Singleton.Reactors.Add(new SP.HwDeferredRS.Reactor());
            ReactorDB.Singleton.Reactors.Add(new SP.HwLowProfileRS.Reactor());

            //this.comboBox1.Items.Add(new Reactor.FxReactor());
            this.comboBox1.Items.AddRange(ReactorDB.Singleton.Reactors.ToArray());
            this.comboBox1.SelectedIndex = 1;
            
            // bind shader to propertyGrid
            _HandleNewShader(null, null);
        }

        private void _HandleGenerateOnly(System.Object sender, System.EventArgs args)
        {
            IReactor reactor = ReactorDB.Singleton.GetReactorByName(mShader.Reactor);
            if (null == reactor)
                return;

            foreach (System.Windows.Forms.TabPage tab in tabControl2.TabPages)
                tab.Controls.Clear();

            tabControl2.TabPages.Clear();

            string[] codeFiles = _SelectedReactor.CodeFiles;

            foreach (string codeFile in codeFiles)
            {
                System.Windows.Forms.TabPage tab = new System.Windows.Forms.TabPage();
                tabControl2.TabPages.Add(tab);

                /*
                System.Windows.Forms.RichTextBox textbox = new System.Windows.Forms.RichTextBox();
                textbox.Dock = System.Windows.Forms.DockStyle.Fill;
                textbox.WordWrap = false;
                textbox.Font = new System.Drawing.Font("Courier New", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
                textbox.ReadOnly = true;
                */

                ScintillaNet.Scintilla textbox = new ScintillaNet.Scintilla();
                textbox.ConfigurationManager.Language = "cpp";
                textbox.Zoom = -2;
                textbox.Margins.Margin0.Width = 30;
                textbox.Dock = System.Windows.Forms.DockStyle.Fill;
                //textbox.Styles[0].Font = new System.Drawing.Font("Courier New", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));

                tab.Controls.Add(textbox);
                tab.Text = mShader.Name + codeFile;

                StringBuilder builder = new StringBuilder();
                reactor.Generate(mShader, codeFile, builder);
                textbox.Text = builder.ToString();
            }
        }

        private void _HandleGenerateAndSave(System.Object sender, System.EventArgs args)
        {
            string[] codeFiles = _SelectedReactor.CodeFiles;

            mSaveResultDlg.DefaultExt = codeFiles[0];
            mSaveResultDlg.Filter = String.Format("{0} files (*{0})|*{0}", codeFiles[0]);
            mSaveResultDlg.FileName = mShader.Name;
            
            if (mSaveResultDlg.ShowDialog(this) == System.Windows.Forms.DialogResult.OK)
            {
                _HandleGenerateOnly(sender, args);

                string dirname = System.IO.Path.GetDirectoryName(mSaveResultDlg.FileName);

                foreach (System.Windows.Forms.TabPage tab in tabControl2.TabPages)
                {
                    System.IO.Stream s = new System.IO.FileStream(dirname + "\\" + tab.Text, System.IO.FileMode.Create);
                    
                    System.IO.StreamWriter w = new System.IO.StreamWriter(s);
                    //w.Write((tab.Controls[0] as System.Windows.Forms.RichTextBox).Text);
                    w.Write((tab.Controls[0] as ScintillaNet.Scintilla).Text);
                    w.Close();
                    s.Close();
                }
            }
        }

        private void _HandleNewShader(object sender, EventArgs e)
        {
            mShader = new Shader("untitled");
            _SelectedReactor.InitShader(mShader);
            this.propertyGrid1.SelectedObject = new ShaderPropertyBag3(mShader, this.propertyGrid1);
        }

        private void _HandleSaveShader(System.Object sender, System.EventArgs args)
        {
            mSaveShaderDlg.FileName = mShader.Name;

            if (mSaveShaderDlg.ShowDialog(this) == System.Windows.Forms.DialogResult.OK)
            {
                mShader.Name = System.IO.Path.GetFileNameWithoutExtension(mSaveShaderDlg.FileName);

                XmlTextWriter textWriter = new XmlTextWriter(new StreamWriter(mSaveShaderDlg.FileName));
                XmlSerializer serializer = new XmlSerializer(typeof(Shader));
                serializer.Serialize(textWriter, mShader);
                textWriter.Close();

                this.propertyGrid1.Refresh();
            }
        }

        private void _HandleLoadShader(System.Object sender, System.EventArgs args)
        {
            if (mLoadShaderDlg.ShowDialog(this) == System.Windows.Forms.DialogResult.OK)
            {
                Shader ret = null;
                try
                {
                    XmlTextReader textReader = new XmlTextReader(new StreamReader(mLoadShaderDlg.FileName));

                    XmlSerializer deserializer = new XmlSerializer(typeof(Shader));
                    ret = (Shader)deserializer.Deserialize(textReader);

                    textReader.Close();

                    mShader = ret;
                    this.propertyGrid1.SelectedObject = new ShaderPropertyBag3(mShader, this.propertyGrid1);

                }
                catch (Exception e)
                {
                    System.Console.WriteLine(e.Message);
                }
            }
        }

        private IReactor _SelectedReactor
        {
            get { return this.comboBox1.SelectedItem as IReactor; }
        }

        private Shader mShader;
        private System.Windows.Forms.SaveFileDialog mSaveResultDlg;
        private System.Windows.Forms.SaveFileDialog mSaveShaderDlg;
        private System.Windows.Forms.OpenFileDialog mLoadShaderDlg;

        private void InitializeComponent()
        {
            this.SuspendLayout();
            // 
            // Testbed
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.ClientSize = new System.Drawing.Size(992, 573);
            this.Name = "Testbed";
            this.ResumeLayout(false);

        }

    }
}
